package com.hueydink.rhythmrouletteclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class MessageProcessor implements Runnable {

	private static String hostName;
	private static int portNumber;
	private AppWindow window;
	private StringBuilder messageBoardText;
	private int playerId;
	private Socket socket = null;
	private PrintWriter printWrtr = null;

	// constructor for MessageProcessor class
	public MessageProcessor(AppWindow window) {
		this.window = window;
		hostName = AppWindow.hostName;
		portNumber = AppWindow.portNumber;
		messageBoardText = new StringBuilder("");

		// establish connection to the server
		try {
			InetAddress address = InetAddress.getByName(hostName);
			socket = new Socket(address, portNumber);
		} catch (IOException iOException) {
			iOException.printStackTrace();
		}

		// instantiate and start input reading thread
		Thread inputReaderThread = new Thread(this, "input_reader");
		inputReaderThread.start();
	}

	/**
	 * START OF RECEIVED MESSAGE PROCESSING METHODS*****************************
	 */
	// display received message in GUI window
	public void postMessage(String message) {
		if (messageBoardText.toString().equals("")) {
			messageBoardText.append(message);
			window.display.asyncExec(new Runnable() {
				public void run() {
					if (!window.styledText.isDisposed()) {
						window.styledText.setText(messageBoardText.toString());
					}
				}
			});
		} else {
			messageBoardText.append("\n" + message);
			window.display.asyncExec(new Runnable() {
				public void run() {
					if (!window.styledText.isDisposed()) {
						window.styledText.setText(messageBoardText.toString());
					}
				}
			});
		}
	}

	// display message and dispatch it according to type
	public void dispatchReceivedMessage(String message) {
		postMessage(message);

		if (message.contains("identification")) {
			handleIdentificationMsg(message);
		}
		if (message.contains("connectioncheck")) {
			handleConnectionCheckMsg();
		}
		if (message.contains("update")) {
			handleUpdateMsg(message);
		}
		if (message.contains("phrase")) {
			handlePhraseMsg(message);
		}
		if (message.contains("error")) {
			handleErrorMsg(message);
		}
	}

	public void handleIdentificationMsg(String message) {
		String[] strings1;
		String[] strings2;
		String playerIdString;

		strings1 = message.split("<playerid>");
		strings2 = strings1[1].split("</playerid>");
		playerIdString = strings2[0];
		playerId = Integer.parseInt(playerIdString);
	}

	public void handleConnectionCheckMsg() {
		sendConnectionCheckMsg();
	}

	public void handleUpdateMsg(String message) {
		/** TODO: Implement ***************************************************/
	}

	public void handlePhraseMsg(String message) {
		String phraseString;
		String[] strings1;
		String[] strings2;

		strings1 = message.split("<phraselist>");
		strings2 = strings1[1].split("</phraselist>");
		phraseString = strings2[0];
		/** TODO: Finish implementing *****************************************/
	}

	public void handleErrorMsg(String message) {
		/** TODO: Implement ***************************************************/
	}

	/**
	 * END OF RECEIVED MESSAGE PROCESSING METHODS*******************************
	 */

	/**
	 * START OF OUTPUT MESSAGE PROCESSING METHODS*******************************
	 */
	public void sendConnectionCheckMsg() {
		String connectionCheckMsg = "<connectioncheck><sender>" + playerId
				+ "</sender></connectioncheck>";

		sendText(connectionCheckMsg);
	}

	public void sendPlayRequestMsg() {
		String playRequestMsg = "<playrequest><sender>" + playerId
				+ "</sender></playrequest>";

		sendText(playRequestMsg);
	}

	public void sendPhraseMsg(String phraseString) {
		String phraseMsg = "<phrase><sender>" + playerId
				+ "</sender><phraselist>" + phraseString
				+ "</phraselist></phrase>";

		sendText(phraseMsg);
	}

	public void sendResultMsg(String scoreString) {
		String resultMsg = "<result><sender>" + playerId + "</sender><score>"
				+ scoreString + "</score></result>";

		sendText(resultMsg);
	}

	public void sendQuitRequestMsg() {
		String quitRequestMsg = "<quitrequest><sender>" + playerId
				+ "</sender></quitrequest>";

		sendText(quitRequestMsg);
	}

	// send text output message to the server
	public void sendText(String outMessage) {

		// get and wrap the output stream
		try {
			printWrtr = new PrintWriter(socket.getOutputStream(), true);
			printWrtr.println(outMessage);
		} catch (IOException iOException1) {
			iOException1.printStackTrace();
		}
	}

	/**
	 * END OF OUTPUT MESSAGE PROCESSING METHODS*********************************
	 */

	// process connection input stream
	public void run() {
		String inMessage;

		try {

			// get and wrap input stream
			BufferedReader bufRdr = new BufferedReader(new InputStreamReader(
					socket.getInputStream()));

			// if available, read a line of text from the input stream
			while (true) {
				if ((inMessage = bufRdr.readLine()) != null) {
					dispatchReceivedMessage(inMessage);
				}
			}
		} catch (IOException iOException) {
			iOException.printStackTrace();
		}
	}

}
